/**
 * @description Create any variable
 * @see         'edu.cmu.cs.stage3.alice.authoringtool.viewcontroller.VariableGUI'
 * @author Jason Pratt
 */

package edu.cmu.cs.stage3.alice.authoringtool.viewcontroller;

import edu.cmu.cs.stage3.resourceBundle.I18n;

import edu.cmu.cs.stage3.alice.authoringtool.AuthoringTool;
import edu.cmu.cs.stage3.alice.authoringtool.AuthoringToolResources;
import edu.cmu.cs.stage3.alice.authoringtool.datatransfer.TransferableFactory;
import edu.cmu.cs.stage3.swing.DialogManager;
import edu.cmu.cs.stage3.util.StringObjectPair;

public class VariableDnDPanel extends edu.cmu.cs.stage3.alice.authoringtool.util.DnDGroupingPanel
       implements edu.cmu.cs.stage3.alice.authoringtool.util.GUIElement, edu.cmu.cs.stage3.alice.authoringtool.util.Releasable {

 protected AuthoringTool authoringTool;
 protected edu.cmu.cs.stage3.alice.core.Variable variable;
 protected javax.swing.JLabel nameLabel = new javax.swing.JLabel();
 protected javax.swing.JTextField textField = new javax.swing.JTextField();

 public String getNameLabel () { return "<name="+nameLabel.getName()+",text="+nameLabel.getText()+": "+textField.getText()+">"; } //L

 protected java.awt.event.FocusListener focusListener = new java.awt.event.FocusAdapter () {
  //Rem @Override
  public void focusLost (java.awt.event.FocusEvent ev) {
   stopEditing();
   }
  };

 protected java.util.Vector popupStructure = new java.util.Vector();
 protected NamePropertyListener namePropertyListener = new NamePropertyListener();

 public VariableDnDPanel () {
  setBackground( AuthoringToolResources.getColor( "variableDnDPanel" ) );

  add( nameLabel, java.awt.BorderLayout.CENTER );
  addDragSourceComponent( nameLabel );

  java.awt.event.MouseListener mouseListener = new edu.cmu.cs.stage3.alice.authoringtool.util.CustomMouseAdapter () {
   //Rem @Override
   public void popupResponse (java.awt.event.MouseEvent ev) {
    VariableDnDPanel.this.updatePopupStructure();
    edu.cmu.cs.stage3.alice.authoringtool.util.PopupMenuUtilities.createAndShowPopupMenu( popupStructure, VariableDnDPanel.this, ev.getX(), ev.getY() );
    }
   };
  addMouseListener( mouseListener );
  nameLabel.addMouseListener( mouseListener );
  grip.addMouseListener( mouseListener );

  textField.setColumns( 5 );

  textField.addActionListener(
    new java.awt.event.ActionListener () {
     public void actionPerformed (java.awt.event.ActionEvent ev) {
      stopEditing();
      }
     }
   );
  textField.addKeyListener(
    new java.awt.event.KeyAdapter () {
     //Rem @Override
     public void keyPressed (java.awt.event.KeyEvent ev) {
      if (ev.getKeyCode() == java.awt.event.KeyEvent.VK_ESCAPE) {
       cancelEditing();
       }
      }
     }
   );
  }

 // edu.cmu.cs.stage3.alice.authoringtool.viewcontroller.VariableGUI.set(VariableGUI.java:29)
 // + edu.cmu.cs.stage3.alice.authoringtool.util.GUIFactory.getVariableDnDPanel(GUIFactory.java:403)
 public void set (AuthoringTool authoringTool, edu.cmu.cs.stage3.alice.core.Variable variable) {
  //if (variable==null) System.out.println("\n\nVariableDnDPanel.java: set: "+namePropertyListener+": ERRO variable="+variable);
  //else System.out.println("VariableDnDPanel.java: set: "+namePropertyListener+": "+variable);
  // namePropertyListener = edu.cmu.cs.stage3.alice.authoringtool.viewcontroller.VariableDnDPanel$NamePropertyListener:
  // variable = edu.cmu.cs.stage3.alice.core.Variable[principal.rode.x]
  if (this.variable != null) {
   this.variable.name.removePropertyListener( namePropertyListener );
   }

  this.authoringTool = authoringTool;
  this.variable = variable;
  nameLabel.setText( AuthoringToolResources.getReprForValue( variable ) );

  if (variable != null) {
   String iconName;
   if (edu.cmu.cs.stage3.alice.core.List.class.isAssignableFrom( variable.getValueClass() )) {
    edu.cmu.cs.stage3.alice.core.List list = (edu.cmu.cs.stage3.alice.core.List)variable.getValue();
    if (list != null) {
     iconName = "types/lists/" + list.valueClass.getClassValue().getName();
    } else {
     iconName = "types/lists";
     }
   } else {
    iconName = "types/" + variable.getValueClass().getName();
    }
   javax.swing.ImageIcon icon = AuthoringToolResources.getIconForValue( iconName );
   if (icon == null) {
    if (edu.cmu.cs.stage3.alice.core.List.class.isAssignableFrom( variable.getValueClass() )) {
     icon = AuthoringToolResources.getIconForValue( "types/lists/other" );
    } else {
     icon = AuthoringToolResources.getIconForValue( "types/other" );
     }
    }
   if (icon != null) {
    nameLabel.setIcon( icon );
    }

   // setTransferable( TransferableFactory.createTransferable( variable ) ); // define ''
   java.awt.datatransfer.Transferable transferable = TransferableFactory.createTransferable( variable ); //L
   setTransferable(transferable); // define 'edu.cmu.cs.stage3.alice.authoringtool.util.DnDGroupingPanel.transferable'
   edu.cmu.cs.stage3.alice.authoringtool.util.DnDManager.setCurrentTransferable(transferable);

   variable.name.addPropertyListener( namePropertyListener );
  } else { // if (variable != null)
   setTransferable( null );
   }
  }

 public void editName () {
  if (variable.name.getStringValue() != null) {
   textField.setText( variable.name.getStringValue() );
   }
  if (this.isAncestorOf( nameLabel )) {
   this.remove( nameLabel );
   }
  if (! this.isAncestorOf( textField )) {
   this.add( textField, java.awt.BorderLayout.CENTER );
   }
  textField.requestFocus();
  textField.addFocusListener( focusListener );
  revalidate();
  }

 public void stopEditing () {
  String prevName = variable.name.getStringValue();
  textField.removeFocusListener( focusListener );
  String valueString = textField.getText();
  try {
   variable.name.set( valueString );
   remove( textField );
   add( nameLabel, java.awt.BorderLayout.CENTER );
   nameLabel.requestFocus();
  } catch( edu.cmu.cs.stage3.alice.core.IllegalNameValueException e) {
   DialogManager.showMessageDialog( e.getMessage(), "Error setting name", javax.swing.JOptionPane.ERROR_MESSAGE );
   textField.setText( prevName );
   }
  revalidate();
  }

 public void cancelEditing () {
  textField.removeFocusListener( focusListener );
  // begin HACK
  remove( textField );
  add( nameLabel, java.awt.BorderLayout.CENTER );
  // end HACK
  revalidate();
  }

 public void updatePopupStructure () {
  popupStructure.clear();

  if (variable != null) {
   popupStructure.add( new StringObjectPair(I18n.getString("msg_rename"), new Runnable() { //  "rename"
    public void run () {
     VariableDnDPanel.this.editName();
     }
    } ) );

   final edu.cmu.cs.stage3.alice.authoringtool.util.WatcherPanel watcherPanel = authoringTool.getWatcherPanel();
   if (watcherPanel.isVariableBeingWatched( variable )) {
    popupStructure.add( new StringObjectPair(I18n.getString("varDnD_stopWatching"), new Runnable() { // "stop watching this variable"
     public void run () {
      watcherPanel.removeVariableBeingWatched( VariableDnDPanel.this.variable );
      }
     } ) );
   } else {
    popupStructure.add( new StringObjectPair(I18n.getString("varDnD_watchThis"), new Runnable() { // "watch this variable"
     public void run () {
      watcherPanel.addVariableToWatch( VariableDnDPanel.this.variable );
      }
     } ) );
    }
   popupStructure.add( new StringObjectPair(I18n.getString("msg_del"), new Runnable() { // "delete"
    public void run () {
     edu.cmu.cs.stage3.alice.authoringtool.util.ElementPopupUtilities.DeleteRunnable deleteRunnable = new edu.cmu.cs.stage3.alice.authoringtool.util.ElementPopupUtilities.DeleteRunnable( variable ); //L, authoringTool );
     deleteRunnable.run();
     }
    } ) );
   }
  } // public void updatePopupStructure()

 public void goToSleep () {}
 public void wakeUp () {}

 public void clean () {
  setTransferable( null );
  }

 public void die () {
  clean();
  }

 //Rem @Override
 public void release () {
  edu.cmu.cs.stage3.alice.authoringtool.util.GUIFactory.releaseGUI( this );
  }

 class NamePropertyListener implements edu.cmu.cs.stage3.alice.core.event.PropertyListener {
  public void propertyChanging (edu.cmu.cs.stage3.alice.core.event.PropertyEvent ev) {}
  public void propertyChanged (edu.cmu.cs.stage3.alice.core.event.PropertyEvent ev) {
   nameLabel.setText( VariableDnDPanel.this.variable.name.getStringValue() );
   }
  }

 }
